package task

import (
	"context"
	"encoding/json"
	"errors"
	"smart-flow/server/config"
	"smart-flow/server/logger"
	"smart-flow/server/net"
	"smart-flow/server/redis"
	"smart-flow/server/utils"
	"time"

	redisLib "github.com/go-redis/redis/v8"
	"go.uber.org/zap"
)

func StartCheckDetectAgent() {
	go checkDetectAgent(config.IspCustom)
	time.Sleep(time.Second)
	go checkDetectAgent(config.IspTelecom)
	time.Sleep(time.Second)
	go checkDetectAgent(config.IspMobile)
	time.Sleep(time.Second)
	go checkDetectAgent(config.IspUnicom)
}

func checkDetectAgent(isp string) {
	for {
		time.Sleep(doCheckDetectAgent(isp))
	}
}

func doCheckDetectAgent(isp string) time.Duration {
	var nextCursor uint64 = 0
	var keys []string
	var err error
	var expiredUids []string
	anyKey := utils.GenIspAnyKey(config.FlowNotV6Key, isp)
	now := time.Now().Unix()
	for {
		keys, nextCursor, err = redis.RDB.HScan(context.Background(), anyKey, nextCursor, "*", 1000).Result()
		if err != nil {
			if errors.Is(err, redisLib.Nil) {
				return 24 * time.Hour
			}
			logger.Logger.Error("[任务] Checker操作Redis异常", zap.Error(err))
			return 24 * time.Hour
		}
		var agentCtx net.AgentContext
		for i := 0; i < len(keys); i += 2 {
			_ = json.Unmarshal([]byte(keys[i+1]), &agentCtx)
			if now-agentCtx.InitTime > 60*60*24*3 { // 超过3天重新探测
				expiredUids = append(expiredUids, agentCtx.Uid)
			}
		}
		if nextCursor == 0 {
			break
		}
	}
	for i := 0; i < len(expiredUids); i += 500 {
		redis.RDB.HDel(context.Background(), anyKey, expiredUids[i:min(len(expiredUids), i+500)]...)
	}
	return 24 * time.Hour
}
